package gis

import (
	"dgo/goutils/utils"
	"fmt"
	"strings"
	"time"
)

const (
	F_10_E9 = 1e+9
	F_10_E3 = 1e+3
)

func IsNmeaChr(c byte) bool {
	return c == '$' || (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || c == ',' || c == '.' || c == '-' || c == '+' || c == '*' || c == '\\' || c == '/' || c == '#' || c == ':'
}

func ConvertNmeaTime(nmeaTime string) (time.Time, error) {
	str := time.Now().UTC().Format("20060102 ") + nmeaTime
	return time.ParseInLocation("20060102 150405", str, time.UTC)
}

/*
speedM: M/H
输入: 当前点(A), 目的点(B), 时刻:T， 速度: speedM
输出: 时刻T点位置
*/
func GenPosiBl(b0, l0, b1, l1 float64, speedM float64, tS uint64) (b, l float64) {
	gen := NewGenPoint(0, func(x1, y1, x2, y2 float64) uint64 {
		dis := CalcuDis(x1, y1, x2, y2)
		h := dis / speedM // dis 距离需要多少小时
		T := h * 3600     // 需要多少秒
		return uint64(T)
	})
	gen.Recycle = false // 不循环
	gen.AddFxiedPoint(l0, b0)
	gen.AddFxiedPoint(l1, b1)
	l, b, _ = gen.GenPoint(tS)
	return
}

func ParseLngLatH(str, sep string) (lng, lat, h float64) {
	strs := strings.SplitN(str, sep, 3)
	lng = utils.StrToFloat64Def(strs[0], 0)
	if len(strs) >= 2 {
		lat = utils.StrToFloat64Def(strs[1], 0)
	}
	if len(strs) >= 3 {
		h = utils.StrToFloat64Def(strs[2], 0)
	}
	return
}

/*
*

	返回一个字符串(32位)
	l:-180~180. 9位小数. 12位999 999999999 (毫米级精度)
	b:-90~90,   9位小数  11位 99 999999999 (毫米级精度)
	h:-99999.999~99999.999  8为 99999 999 (毫米级精度)
*/
func BLH2String(b, l, h float64) string {
	sign := byte(0)
	if b < 0 {
		sign = byte(utils.SetBitValue0(uint64(sign), 0, true))
		b = -b
	}

	if l < 0 {
		sign = byte(utils.SetBitValue0(uint64(sign), 1, true))
		l = -l
	}

	if h < 0 {
		sign = byte(utils.SetBitValue0(uint64(sign), 2, true))
		h = -h
	}

	if b > 99.999999999 {
		b = 99.999999999
	}

	if l > 999.999999999 {
		l = 999.999999999
	}

	if h > 99999.999 {
		h = 99999.999
	}

	b = b * F_10_E9
	l = l * F_10_E9
	h = h * F_10_E3

	return fmt.Sprintf("%.1d%.11d%.12d%.8d", sign, int(b), int(l), int(h))
}

func BLHStringBLH(blhstr string) (b, l, h float64, ok bool) {
	ok = false
	if len(blhstr) != 32 {
		return
	}
	sign := uint64(utils.StrToIntDef(blhstr[0:1], 0))

	s0 := blhstr[1:12]
	b = float64(utils.StrToInt64Def(s0, 0)) / F_10_E9
	if utils.GetBitValue0(sign, 0) == 1 {
		b = -b
	}

	s0 = blhstr[12:24]
	l = float64(utils.StrToInt64Def(s0, 0)) / F_10_E9
	if utils.GetBitValue0(sign, 1) == 1 {
		l = -l
	}

	s0 = blhstr[24:]
	h = float64(utils.StrToInt64Def(s0, 0)) / F_10_E3
	if utils.GetBitValue0(sign, 2) == 1 {
		h = -h
	}

	ok = true
	return
}

func IsHexChar(chr rune) bool {
	c := byte(chr)
	return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')
}

/*
*

	hexstr 不能有空格, 和其他字符, 只能是16进制字符串
*/
func HexStrToBuf(hexstr string) []byte {
	hexstrArr := []rune(hexstr)
	l := len(hexstrArr)
	l2 := l >> 1

	rval := make([]byte, 0, l2)
	i := 0

	for {
		if (i + 1) >= l {
			break
		}
		if IsHexChar(hexstrArr[i]) && IsHexChar(hexstrArr[i+1]) {
			v := HexValue(hexstrArr[i])<<4 + HexValue(hexstrArr[i+1])
			i += 2
			rval = append(rval, byte(v))
		} else {
			break
		}
	}
	return rval

}

func HexValue(chr rune) int {
	c := int(chr)
	if (c >= '0') && (c <= '9') {
		return c - '0'
	} else if c >= 'a' && c <= 'f' {
		return 10 + c - 'a'
	} else {
		return 10 + c - 'A'
	}
}

func innerBufToHexStr(buf []byte) string {
	rval := ""
	i := 0
	l := len(buf)
	for _, v := range buf {
		if (l > 0) && (i >= l) {
			break
		}
		rval = fmt.Sprintf("%s%.2X", rval, v)
		i++
	}

	return rval
}
